﻿using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Client.AndroiD
{
    [Service]
    public class FakeScannerService : Service
    {
        static readonly string TAG = typeof(FakeScannerService).FullName;

        public const string ACTION_START_SERVICE = "FakeScannerService.START_SERVICE";

        bool isStarted { get; set; }

        public override void OnCreate()
        {
            base.OnCreate();
        }

        public override IBinder OnBind(Intent intent)
        {
            return null;
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            switch (intent.Action)
            {
                case ACTION_START_SERVICE:
                    start();
                    break;
            }

            return StartCommandResult.Sticky;
        }

        void start()
        {
            if (isStarted)
            {
                Log.Info(TAG, "OnStartCommand: The service is already running.");
            }
            else
            {
                RegisterMyBroadcastReceiver();

                Log.Info(TAG, "OnStartCommand: The service is starting.");

                RegisterForegroundService();

                isStarted = true;
            }
        }

        public override void OnDestroy()
        {
            UnregisterMyBroadcastReceiver();
            Log.Info(TAG, "OnStartCommand: The service is stopping.");

            Log.Info(TAG, "OnDestroy: The started service is shutting down.");

            // Remove the notification from the status bar.
            var notificationManager = (NotificationManager)GetSystemService(NotificationService);
            notificationManager.Cancel(SERVICE_RUNNING_NOTIFICATION_ID);

            isStarted = false;

            base.OnDestroy();
        }

        #region 通知栏

        public const int SERVICE_RUNNING_NOTIFICATION_ID = 48001;

        string createNotificationChannel(string channnelId, string channnelName)
        {
            NotificationChannel chan = new NotificationChannel(channnelId, channnelName, NotificationImportance.None);
            // chan.LightColor = 30000; // 在安卓10上设置颜色好像没没有什么效果
            chan.LockscreenVisibility = NotificationVisibility.Private;
            NotificationManager service = (NotificationManager)GetSystemService(NotificationService);
            service.CreateNotificationChannel(chan);
            return channnelId;
        }

        void RegisterForegroundService()
        {
            Notification.Builder builder = null;

            if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
            {
                string channelId = createNotificationChannel("FakeScannerService Notification Id", "FakeScannerService Notification");
                builder = new Notification.Builder(this, channelId);
            }
            else
            {
                // 修复 android 5 运行异常
                // 运行带 2 个参数的 Builder 会报错
                builder = new Notification.Builder(this);
            }

            Notification notification = builder
                .SetContentTitle(Resources.GetString(Resource.String.app_name))
                .SetContentText("已启用扫码转发服务")
                .SetSmallIcon(Resource.Drawable.pc)
                .SetContentIntent(BuildIntentToShowMainActivity())
                .SetOngoing(true) // 表示它为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
                // .SetProgress(100, 90, false) // max:进度条最大数值  、progress:当前进度、indeterminate:表示进度是否不确定，true为不确定
                                             // 一个通知最多可以提供三个操作按钮，让用户可以快速响应，例如暂停提醒，甚或回复短信。
                                             //.AddAction(BuildRestartTimerAction())
                                             //.AddAction(BuildStopServiceAction())
                .Build();

            // Enlist this instance of the service as a foreground service
            StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
        }

        /// <summary>
        /// Builds a PendingIntent that will display the main activity of the app. This is used when the 
        /// user taps on the notification; it will take them to the main activity of the app.
        /// </summary>
        /// <returns>The content intent.</returns>
        PendingIntent BuildIntentToShowMainActivity()
        {
            // 在 MainActivity 的 Activity 标签中设置 LaunchMode = Android.Content.PM.LaunchMode.SingleInstance 来保证返回到已打开的 Activity
            // 还要在 MainActivity 中禁止 Back 返回键对 Activity 的销毁
            var notificationIntent = new Intent(this, typeof(MainActivity));
            notificationIntent.SetAction("main");
            notificationIntent.SetFlags(ActivityFlags.SingleTop | ActivityFlags.ClearTask); // 重新打开前需要进入 Destory() 销毁 MessageCenter
            notificationIntent.SetFlags(ActivityFlags.ReceiverVisibleToInstantApps);
            notificationIntent.PutExtra(MainActivity.SERVICE_STARTED_KEY, true);

            #region PendingIntentFlags 解释
            // FLAG_ONE_SHOT        表示返回的PendingIntent仅能执行一次，执行完后自动取消
            // FLAG_NO_CREATE       表示如果描述的PendingIntent不存在，并不创建相应的PendingIntent，而是返回NULL
            // FLAG_CANCEL_CURRENT  表示相应的PendingIntent已经存在，则取消前者，然后创建新的PendingIntent，这个有利于数据保持为最新的，可以用于即时通信的通信场景
            // FLAG_UPDATE_CURRENT  表示更新的PendingIntent
            #endregion

            var pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, PendingIntentFlags.UpdateCurrent);
            return pendingIntent;
        }

        #endregion

        #region 广播接收

        MyBroadcastReceiver mReceiver { get; set; }

        IntentFilter mFilter { get; set; }

        void RegisterMyBroadcastReceiver()
        {
            mFilter = new IntentFilter(StaticInfo.IntentFilter);
            mReceiver = new MyBroadcastReceiver(true, StaticInfo.KeyOfData);

            this.RegisterReceiver(mReceiver, mFilter);
        }

        void UnregisterMyBroadcastReceiver()
        {
            this.UnregisterReceiver(mReceiver);
        }

        #endregion
    }
}